package com.yuanye.gwcit.activity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.util.Size;
import android.view.View;
import android.widget.Button;
import android.widget.TextClock;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.mlkit.vision.MlKitAnalyzer;
import androidx.camera.view.CameraController;
import androidx.camera.view.LifecycleCameraController;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.core.util.Consumer;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.mlkit.vision.barcode.BarcodeScanner;
import com.google.mlkit.vision.barcode.BarcodeScannerOptions;
import com.google.mlkit.vision.barcode.BarcodeScanning;
import com.google.mlkit.vision.barcode.common.Barcode;
import com.yuanye.gwcit.R;
import com.yuanye.gwcit.widget.QrCodeDrawable;
import com.yuanye.gwcit.widget.QrCodeViewModel;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static androidx.camera.view.CameraController.COORDINATE_SYSTEM_VIEW_REFERENCED;

public class CameraActivity extends AppCompatActivity {

    public final String TAG = CameraActivity.class.getSimpleName();

    private ExecutorService cameraExecutor;
    private boolean isNeedFlip = true;
    private PreviewView previewView;
    private LifecycleCameraController cameraController;
    private BarcodeScanner barcodeScanner;
    private TextView textView;
    private String qrCodeValue = "";
    private ImageCapture imageCapture;
    private File outputDirectory;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        textView = findViewById(R.id.tvTips);
        previewView = findViewById(R.id.previewView);
        //是否镜像
        if (isNeedFlip){
            previewView.setImplementationMode(PreviewView.ImplementationMode.COMPATIBLE);
            previewView.setScaleX(-1f);
        }
        Button btnTest = findViewById(R.id.btnTest);
        btnTest.setText("拍照");
        btnTest.setVisibility(View.GONE);
        cameraExecutor = Executors.newSingleThreadExecutor();
        startCamera();
    }

    private void startCamera(){
        //相机周期控制器
        cameraController = new LifecycleCameraController(this);
        imageCapture = new ImageCapture.Builder().build();
        //绑定到activity的生命周期
        cameraController.bindToLifecycle(this);
        //设置默认相机为外部摄像头
        CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_EXTERNAL).build();
        cameraController.setCameraSelector(cameraSelector);
        //构造图片流分析器
        BarcodeScannerOptions options = new BarcodeScannerOptions.Builder()
                .setBarcodeFormats(Barcode.FORMAT_QR_CODE)
                .build();
        barcodeScanner = BarcodeScanning.getClient(options);
        MlKitAnalyzer analyzer = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            analyzer = new MlKitAnalyzer(
                    List.of(barcodeScanner),
                    COORDINATE_SYSTEM_VIEW_REFERENCED,
                    ContextCompat.getMainExecutor(this),
                    new Consumer<MlKitAnalyzer.Result>() {
                        @Override
                        public void accept(MlKitAnalyzer.Result result) {
                            List<Barcode> barcodeResults = result != null ? result.getValue(barcodeScanner) : null;
                            if (barcodeResults == null || barcodeResults.isEmpty() || barcodeResults.get(0) == null) {
                                previewView.getOverlay().clear();
                                previewView.setOnTouchListener((v, event) -> false); // no-op
                                textView.setText("");
                                return;
                            }

                            Barcode qrCode = barcodeResults.get(0);
                            QrCodeViewModel qrCodeViewModel = new QrCodeViewModel(qrCode);
                            if (isNeedFlip) qrCodeViewModel.setFlip();
                            QrCodeDrawable qrCodeDrawable = new QrCodeDrawable(qrCodeViewModel);

                            previewView.setOnTouchListener(qrCodeViewModel.getQrCodeTouchCallback());
                            previewView.getOverlay().clear();
                            previewView.getOverlay().add(qrCodeDrawable);
                            if (qrCode.getDisplayValue().equals("hello")){
                                Intent data = new Intent();
                                data.putExtra("info", "二维码验证成功: hello");
                                setResult(200, data);
                                finish();
                            }else{
                                if (!qrCode.getDisplayValue().equals(qrCodeValue))
                                    qrCodeValue = qrCode.getDisplayValue();
                                    textView.setText("识别出二维码："+qrCodeValue);
                            }
                        }
                    }
            );
        }
        //添加分析器
        if (analyzer != null){
            cameraController.setImageAnalysisAnalyzer(
                    ContextCompat.getMainExecutor(this), analyzer);
        }
        imageCapture = new ImageCapture.Builder().build();

        cameraController.setPreviewTargetSize(new CameraController.OutputSize(new Size(1280, 720)));
        //添加相机控制器
        previewView.setController(cameraController);
    }

    private void startCamera2() {
        // 将Camera的生命周期和Activity绑定在一起（设定生命周期所有者），这样就不用手动控制相机的启动和关闭。
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);
            cameraProviderFuture.addListener(() -> {
                try {
                    ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                    Preview preview = new Preview.Builder().build();
                    preview.setSurfaceProvider(previewView.getSurfaceProvider());
                    CameraSelector cameraSelector = new CameraSelector.Builder().build();
                    imageCapture = new ImageCapture.Builder().build();
                    cameraProvider.unbindAll();
                    cameraProvider.bindToLifecycle(this, cameraSelector, imageCapture, preview);
                }catch (Exception e){
                    e.printStackTrace();
                    Log.e(TAG, "用例绑定失败！" + e);
                }
            }, ContextCompat.getMainExecutor(this));
        }
    }

    private void takePhoto() {
        // 确保imageCapture 已经被实例化, 否则程序将可能崩溃
        if (imageCapture != null) {
            File photoFile = new File(getExternalFilesDir(null),
                    "test.jpg");

            // 创建 output option 对象，用以指定照片的输出方式
            ImageCapture.OutputFileOptions.Builder builder = new ImageCapture.OutputFileOptions.Builder(photoFile);
            if (isNeedFlip){
                ImageCapture.Metadata metadata = new ImageCapture.Metadata();
                metadata.setReversedHorizontal(true);
                builder.setMetadata(metadata);
            }
            // 执行takePicture（拍照）方法
            cameraController.takePicture(builder.build(),
                    cameraExecutor,
                    new ImageCapture.OnImageSavedCallback() {// 保存照片时的回调
                        @Override
                        public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                            Uri savedUri = Uri.fromFile(photoFile);
                            String msg = "照片捕获成功! " + savedUri;
//                            Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
                            Log.d(TAG, msg);
                            Intent data = new Intent();
                            data.putExtra("info", msg);
                            setResult(200, data);
                            finish();
                        }

                        @Override
                        public void onError(@NonNull ImageCaptureException exception) {
                            Log.e(TAG, "Photo capture failed: " + exception.getMessage());
                            Intent data = new Intent();
                            data.putExtra("info", "Photo capture failed: " + exception.getMessage());
                            setResult(-1, data);
                            finish();
                        }
                    });
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cameraExecutor.shutdown();
        if (barcodeScanner != null)
            barcodeScanner.close();
    }

    public void topClick(View view){
        if (view.getId() == R.id.btnTest){
            takePhoto();
            return;
        }
        if (view.getId() == R.id.btnPass){
            setResult(200);
        }
        finish();

    }
}
